[Apiary]Markdownで始めるAPI開発とAPIドキュメント作成
APIを作るとき
みなさん、毎日API使ってますか?私は、ワンライナーでAPIをコールすることにハマっています。さて、いつも使っているAPIを作る側になったとき、どのように設計していますでしょうか?また、作ったAPIをどのように使ってもらっていますか?そんな疑問に応えるサービスがApiaryです。
Apiaryとは?
Apiaryは、REST APIをサクッと書けるサービスです。また、APIドキュメントも生成してくれます。モックサーバも提供してくれます。API利用サンプルコードも作ってくれます。うん、使わないって選択肢は無いですねw。
無料登録すると早速使えるようになります。チームでプライベートなAPI開発をしたければ有料プランを選択してください。
API開発の流れ
API開発の流れは、まずはじめにMarkdown形式でドキュメントを書きます。既にサンプルがあるのでこれを使ってみましょう。
右側にドキュメントのプレビューが現れましたね。さっそく使ってみましょう。List all Notesを選択します。すると、APIのモックを利用できる画面が出てきます。
ドキュメントを書いただけなのにAPIを実行できました!
CORS設定
API利用時にCORS(クロスドメインアクセス)をしたいときがありますよね。Apiaryの設定画面でON/OFF可能です。
サンプルコードの利用
できあがったモックAPIサーバを利用するサンプルコードも自動生成されます。これはありがたいですね!
cURL
curl --include \ 'http://private-ee96-satoshi7.apiary-mock.com/notes'
Java
import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; import javax.ws.rs.core.Response; import javax.ws.rs.core.MediaType; Client client = ClientBuilder.newClient(); Response response = client.target("http://private-ee96-satoshi7.apiary-mock.com") .path("/notes") .request(MediaType.TEXT_PLAIN_TYPE) .get(); System.out.println("status: " + response.getStatus()); System.out.println("headers: " + response.getHeaders()); System.out.println("body:" + response.readEntity(String.class));
JavaScript
var Request = new XMLHttpRequest(); Request.open('GET', 'http://private-ee96-satoshi7.apiary-mock.com/notes'); Request.onreadystatechange = function () { if (this.readyState === 4) { console.log('Status:', this.status); console.log('Headers:', this.getAllResponseHeaders()); console.log('Body:', this.responseText); } }; Request.send(JSON.stringify(body));
Node.js
var request = require('request'); request('http://private-ee96-satoshi7.apiary-mock.com/notes', function (error, response, body) { console.log('Status:', response.statusCode); console.log('Headers:', JSON.stringify(response.headers)); console.log('Response:', body); });
Perl
require LWP::UserAgent; my $ua = LWP::UserAgent->new; my $response = $ua->get("http://private-ee96-satoshi7.apiary-mock.com/notes"); print $response->as_string;
Python
from urllib2 import Request, urlopen request = Request('http://private-ee96-satoshi7.apiary-mock.com/notes') response_body = urlopen(request).read() print response_body
PHP
<?php $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "http://private-ee96-satoshi7.apiary-mock.com/notes"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_HEADER, FALSE); $response = curl_exec($ch); curl_close($ch); var_dump($response); [/code] <h4>Ruby</h4> <h4>Go</h4> package main import ( "fmt" "io/ioutil" "net/http" ) func main() { client := &http.Client{} req, _ := http.NewRequest("GET", "http://private-ee96-satoshi7.apiary-mock.com/notes", nil) resp, err := client.Do(req) if err != nil { fmt.Println("Errored when sending request to the server") return } defer resp.Body.Close() resp_body, _ := ioutil.ReadAll(resp.Body) fmt.Println(resp.Status) fmt.Println(string(resp_body)) }
C#
using System; using System.Net.Http; var baseAddress = new Uri("http://private-ee96-satoshi7.apiary-mock.com/"); using (var httpClient = new HttpClient{ BaseAddress = baseAddress }) { using(var response = await httpClient.GetAsync("notes")) { string responseData = await response.Content.ReadAsStringAsync(); } }
VisualBasic
Dim request = TryCast(System.Net.WebRequest.Create("http://private-ee96-satoshi7.apiary-mock.com/notes"), System.Net.HttpWebRequest) request.Method = "GET" request.ContentLength = 0 Dim responseContent As String Using response = TryCast(request.GetResponse(), System.Net.HttpWebResponse) Using reader = New System.IO.StreamReader(response.GetResponseStream()) responseContent = reader.ReadToEnd() End Using End Using
Groovy
import groovyx.net.http.RESTClient import static groovyx.net.http.ContentType.JSON import groovy.json.JsonSlurper import groovy.json.JsonOutput @Grab (group = 'org.codehaus.groovy.modules.http-builder', module = 'http-builder', version = '0.5.0') def client = new RESTClient("http://private-ee96-satoshi7.apiary-mock.com") response = client.get( path : "/notes") println("Status:" + response.status) if (response.data) { println("Content Type: " + response.contentType) println("Body:\n" + JsonOutput.prettyPrint(JsonOutput.toJson(response.data))) }
Objective-C
NSURL *URL = [NSURL URLWithString:@"http://private-ee96-satoshi7.apiary-mock.com/notes"]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; [request setHTTPMethod:@"GET"]; NSURLSession *session = [NSURLSession sharedSession]; NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error) { if (error) { // Handle error... return; } if ([response isKindOfClass:[NSHTTPURLResponse class]]) { NSLog(@"Response HTTP Status code: %ld\n", (long)[(NSHTTPURLResponse *)response statusCode]); NSLog(@"Response HTTP Headers:\n%@\n", [(NSHTTPURLResponse *)response allHeaderFields]); } NSString* body = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"Response Body:\n%@\n", body); }]; [task resume];
Swift
let url = NSURL(string: "http://private-ee96-satoshi7.apiary-mock.com/notes")! let request = NSMutableURLRequest(URL: url) let session = NSURLSession.sharedSession() let task = session.dataTaskWithRequest(request) { (data: NSData!, response: NSURLResponse!, error: NSError!) in if error != nil { // Handle error... return } println(error) println(response) println(NSString(data: data, encoding: NSUTF8StringEncoding)) }
Swift Representor
import Alamofire import Representor let blueprint = Blueprint(named: "blueprint.json", bundle: nil) let baseURL = NSURL(string: "http://private-ee96-satoshi7.apiary-mock.com/") if let transition = blueprint?.transition("Notes Collection", action: "List all Notes") { request(baseURL, transition, parameters:parameters) .response { (request, response, data, error) in // Handle the response } }
まとめ
Markdownを書いたらAPIとドキュメントが出来上がっていますので、クライアントサイドとサーバーサイドで後からごにょごにょ繋げるのではなく、先にAPI(アプリケーションをプログラミングするときに使うインタフェース)部分を決めることで、開発は大分楽になるのではないでしょうか。